Блин - видел очень давно похожую реализацию, но походу 100500 людей так и не научились это делать, написать чтоли самому...
Суть - для продажи предметов, войск, всяких древ талантов - используйте спеллбук + способности на основе - поставка ресурсов.
Помещаем в спеллбук до 11 способностей на основе "Поставка ресусов" - это аналог канала, настраивается приказ и прочее, но самое главное есть поля - стоймость золотом, стоймость деревом, т.е эта абилка может требовать не только ману но и золото с деревом. Так же там стоит вкладка, заряд игрока владельца - очень важная настройка:
Заряд игрока владельца включен - тогда за каст ресурсы будут списыватся только у игрока владельца юнита, при этом неважно что вашим юнитом управляет другой игрок.
Заряд игрока владельца выключен - тогда при касте этой абилки ресурсы будут списыватся со счета игрока, который и отдал приказ, это даже можно отследить, но немного геморойно:
Суть: делаем триггер который срабатывает на приказ каста поставки ресурсов, или события юнит начинает каст способности, условия по вкусу и действия - создать еще 1 триггер, в события которого добавить - ресурсы игрока N изменились (для каждого игрока способного купить), условием - ресурсов стало меньше на стоймость каста абилки, и действие - выключить триггер, записать GetTriggerPlayer() в глобальную переменную или в еще куда, это и будет наш игрок который кликнул на поставку ресурсов, ну и далее утилизируем триггер, удаляя действия. Можно написать все действия в условии, тогда не придется удалять действия.
Так можно отследить кто кастанул абилку поставки ресурсов если юнитом управляют несколько игроков.
Ну карта защищена от ковырялкиных, весь код нужно править.
Да и вовсе понадобится JNGP чтобы сохранить изменения в этой карте.
Карта защищена довольно примитивно, если вы не смогли её запустить - вам явно не стоит этим заниматся.
Очередной проект задохнулся за недостатком энтузиазма...
Ну почему же сразу "задохнулся"? АоС как жанр в целом может развиваться бесконечно, и любую версию после релизной можно воспринимать как финальную, пока не выйдет следующая.
Автору: вообще-то говоря, подобные вещи обычно публикуют в блогах. В QA (этом разделе) тоже можно, конечно, но вопросы обычно очень быстро пропадают из поля зрения пользователей сайта, а поиск продолжателя может занять значительное время. Вообще, я бы глянул исходник интереса ради. Продолжать гарантированно не буду, но мб на досуге что-нибудь запилю/перепилю для развлечения и скину тебе. Впрочем, тоже не обещаю.
Остальных комментаторов хотелось бы попросить воздержаться от выкрикивания мнений без конструктива по существу.
Размер карты-то изначально известен, можно обойтись и рандомом между статичными цифирями. Думал над этим вариантом тоже, значит будем пользовать его. nvc123:
к слову этот вообще не рабочий ибо количество итераций циклов может превысить лимит потока и тогда триггер просто обрубится
Ставить таймеры по 0.5 сек? Такого вида?
loop
exitwhen IsUnitDeadBJ(BET) or BECo > 20
if (TimerGetRemaining(t) <= 0) then
call MoveLocation( p, GetRandomReal ( X1, X2), GetRandomReal (Y1, Y2))
call SetUnitMoveSpeed( BET, 500.00 )
call IssuePointOrderLocBJ( BET, "move", p )
set BECo = BECo + 0.5
call TimerStart(t, 0.5, false, null)
endif
endloop
Таймер не вейт, он запустить новый Поток когда истечет, в функции старта таймера 4 параметра, таймер, время, периодичный буль и ссылка на код .
вместо null нужно вписать function Имя функции
functiom Timer_UnitMove_Expires takes nothing returns nothing
// эта функция будет вызыватся каждые 0.50 сек. пока не остановить таймер
endfunction
function A takes nothing returns nothing
local timer t = CreateTimer( )
call TimerStart( t, 0.50, true, function Timer_UnitMove_Expires )
set t = null
endfunction
Чтобы передавать информацию между функциями нужны так называемые Аттачи, нужно прикрепить данные к триггеру или таймеру, потому что мы можем получить ссылку на них в запущенных ими потоками.
Про хештаблицу куча данных на сайте, SaveUnitHandle( хештаблица, ключ 1, ключ 2, сам юнит )
за подобное положена смертная казнь
вейт плох тем что он не точен (погрешность в 0,1 секунды и работает во время паузы игры)
и тем что всякие вырезано используют его там где надо использовать таймеры
почитай про то как правильно использовать таймеры
чтобы понимать где нужен вейт а где таймер
вот две статьи
Sacar777, выведи после MultiboardGetItem(udg_JC_Board, i-1, 1)
на экран следующий текст
I2S(GetHandleId(q1))
I2S(GetHandleId(q2))
если q2 по каким то причинам не создаётся то это скажет об этом
стоп
а какой у тебя размер столбца стоит?
мб просто ячейка q1 перекрывает собой ячейку q2
и размер 10 это очень много
ведь в отличие от гуи тут размер в сотых указывается
то есть если в гуи размер 10 то тут должен быть 0.1
поставь в MultiboardSetItemWidth(q1, 10.00)
вместо 10.00 0.1 и проверь
если 0.1 не сработает то поставь 0.02
если и это не сработает то отпиши сюда
я тогда раскапаю свой старый мультибоард и сравню с твоим
Событие - постройка завершена
Действие: Если тип юнита (построенное здание) = стена,
то установить переменую-точку = позиция (построенного здания),
удалить (построенное здание)
создать декорацию типа "Стена-декорация" в точке-переменной
удалить точку
Пишу с работы, редактора под рукой нет. Прошу за ошибки и неточности простить))
Ну качаешь остюда JNGP, тут поправлено туча багов, спс Ханашиби.
Ставим по инструкции, запускаем ро, потом отрубаем USWE опции вроде там кастом тайслетов да кастом гуи триггеров, оно нафиг ненадо и нередко ломает совместимость с другими редакторами карт wc3.
Сжасс там есть, все должно изи работать.
Если нужен мемхак, скину код из своей карты с инструкциями что к чему.
Еще вопросы?
Но ведь сами по себе ошибки не происходят.
Причина подобного это А) - невнимательность либо твоя либо автора В) - программное обеспечение
Что бы в дальнейшем все было окей, просто сначала потести карту полностью что бы знать что и как должно быть, а потом вноси изменения, будь внимательней.
Еще советую связаться с автором и поговорить с ним об этой проблеме, или запросить у него еще 1 исходник да бы сверЯться с ним.
Происходящее здесь напомнило мне один случай из моего далекого прошлого. В те времена я еще только начинал осваивать редактор. Одна из тем, которая меня заинтересовала и по которой мне не удалось найти достаточно полной информации - утечки. Тогда я пошел на один форум и задал простой вопрос о том, как определить наличие и степень серьезности утечек в карте, не перебирая весь код. В результате я получил тонну флуда и "ответ от профи", с которым все в итоге согласились - фрагмент кода с ценным указанием "если это число растет быстро - утечек много, если медленно - мало или нет вовсе". Код представлял из себя таймер с малым периодом, который создавал объект, брал его хендл, писал в чат и удалял объект, но был один нюанс - создаваемый объект утекал на каждой итерации таймера.
Kirill_Wolkov, ну ты редкостный растыка....
Что я вижу в его карте - плоская пустая карта с натыканными рудниками и войсками, что к чему и триггеры на гуях, скопированные откуда то, дальше самое интересное - у чувака расширенное гуи, событие триггера Таймер Истекает( CreateTimer() ) условие нет, дейтсвие создать костяной завод нежити в такой то точки, и таких триггеров с десяток для каждого здания.
Нет рили, это уже зашквар - учить гуишников че им делать, неужели так сложно почитать статьи и подумать?
Чтобы таймер истек его нужно не только создать но еще и запустить, не надо делать 1000 триггеров, можно создать всех юнитов в одном, потом нужно создать переменную типа - таймер, потому что гуи, тут динамического создания триггеров\таймеров нет для вас, забудьте про все рус. и расширенные гуи, на нормальном как делали близзарды научитесь делать мили карты... Простите, но у меня бомбит...
Потом блин ну вы хоть одну карту из кампании смотрели? кто спауни здания то? Создают изначально всю базу на карте, потом если нужно чтобы она появилась в процессе игры её скрывают и паузят.
Ужас.
Пока нет желания разбираться, что у тебя так, а что не так. Но вижу, что переменная Window не назначена окну, а ещё как бы создаются в цикле одновременно 10 окон, которые потом все одновременно ждут 50 секунд. Вот скрин действий триггера вместо двух твоих, секунда ожидания поставлена для того, чтобы увидеть пропадание окна таймера.
устанавливает юниту, записанному в переменную udg_u (в редакторе переменных просто u), ману в количестве равном 1000
также доступно добавление юниту здоровья или маны:
Потому что вы блокируете мультишот. Запрет спеллбука не запрещает способности, находящиеся в нем. Но запрет самих способностей, внезапно, запрещает их.
ScopteRectuS, Я решил проблему там баг, если указать регион как точку назначения портала, то с ним триггеры перестают работать. Я просто указал другой регион. biridius, Ну это альфа версия, за 5 мин сделал, знаю об утечках.
Карта без тумана войны и чёрной маски? Если с ними, то зачем прозрачность в пределах видимости юнита? Просто всей пещере непрозрачность 15%, и каждую секунду делать проверку, если никаких юнитов игрока нет в пещере, то непрозрачность 100%, если есть, то 15%.
Чтобы было норм читать, надо хотя бы выделять содержимое каждого блока (типа function/endfunction, if/endif, loop/endloop) табуляцией. Если блок внутри блока, то двойная табуляция, и т. д.
В vJASS и cJASS не стоит использовать одновременно C-подобный и Turing-подобный (стандартный JASS) синтаксис.
А если ты неправильно поставишь пробелы, запятые или кавычки, тебе об этом скажет парсер =)
Во-первых, что есть "локальный таймер" ? Это таймер записанный в локальную переменную?
Во-вторых, зачем тебе точка, если ты используешь XY ? Работай с ними
В-третьих, да. Использование в течении всей игры одной заранее созданной точки вызывает меньше нагрузки чем постоянно создание и удаление новых (кто-то там доказывал на примере и цифрами что от ремувнутых точке всё равно остаётся шлак в памяти...)
расстояние до найденного ближайшего лучше не пересчитывать каждый раз, а хранить в переменной; еще можно обойтись без корня, а сравнивать сразу квадраты расстояний
возможно проблема в сравнении неинициализированной (например int i вместо int i = 1) переменной (unit FIRST == null)
вместо этого юзай boolean флаг или проверку на сохраненное расстояние до ближайшего, например что оно больше -1
Чтобы было норм читать, надо хотя бы выделять содержимое каждого блока (типа function/endfunction, if/endif, loop/endloop) табуляцией. Если блок внутри блока, то двойная табуляция, и т. д.
В vJASS и cJASS не стоит использовать одновременно C-подобный и Turing-подобный (стандартный JASS) синтаксис.
А если ты неправильно поставишь пробелы, запятые или кавычки, тебе об этом скажет парсер =)
Во-первых, что есть "локальный таймер" ? Это таймер записанный в локальную переменную?
Во-вторых, зачем тебе точка, если ты используешь XY ? Работай с ними
В-третьих, да. Использование в течении всей игры одной заранее созданной точки вызывает меньше нагрузки чем постоянно создание и удаление новых (кто-то там доказывал на примере и цифрами что от ремувнутых точке всё равно остаётся шлак в памяти...)
расстояние до найденного ближайшего лучше не пересчитывать каждый раз, а хранить в переменной; еще можно обойтись без корня, а сравнивать сразу квадраты расстояний
возможно проблема в сравнении неинициализированной (например int i вместо int i = 1) переменной (unit FIRST == null)
вместо этого юзай boolean флаг или проверку на сохраненное расстояние до ближайшего, например что оно больше -1
Нашёл решение для тебя.
Пол-ночи провозился, но нашёл. почему-то это стало делом чести - открыть сию карту в редакторе
В общем, берёшь архив из аттача и тупо суёшь папку UI в корень варкрафта. После этого карта будет открываться любым вариантом редактора - как JNGP (любым), так и (даже!) стандартным.
Важно: локальные файлы должны быть разрешены.
Только там такой срач и дичь, что лучше реально своими руками с нуля писать...
Проблема решена. Я сделал так: Удалил все триггеры и потом по папочке восстанавливал, когда нашли в чем проблема удалили триггер и все заработало, спасибо за помощь!
Чтобы было норм читать, надо хотя бы выделять содержимое каждого блока (типа function/endfunction, if/endif, loop/endloop) табуляцией. Если блок внутри блока, то двойная табуляция, и т. д.
В vJASS и cJASS не стоит использовать одновременно C-подобный и Turing-подобный (стандартный JASS) синтаксис.
А если ты неправильно поставишь пробелы, запятые или кавычки, тебе об этом скажет парсер =)
Во-первых, что есть "локальный таймер" ? Это таймер записанный в локальную переменную?
Во-вторых, зачем тебе точка, если ты используешь XY ? Работай с ними
В-третьих, да. Использование в течении всей игры одной заранее созданной точки вызывает меньше нагрузки чем постоянно создание и удаление новых (кто-то там доказывал на примере и цифрами что от ремувнутых точке всё равно остаётся шлак в памяти...)
Rасательно вопроса как добавить в книгу заклинаний больше 12 скиллов - можно добавить книгу в книгу и новой книге сделать ещё несколько скиллов и ещё 1 или несколько книг. В каждую книгу можно ещё по книге и так далее.
Главное - ID приказа у всех книг должны быть разные.
Иконки способностей кольца, когтей и т.д. отображаться не будут, ты можешь отображать скиллы-пустышки, а (только это на всякий случай предложенный вариант!) герою выдавать сам предмет, предварительно вытряхнув из его инвентаря все предметы на пол. После добавления в пустой инвентарь нужного предмета, например когтей - заполняем ещё 4 слота предметами-пустышками, затем даём предмет со способностью "предметы герой", у этой способности для предмета должна стоять галочка "относится к предмету", обязательно. После этого инвентарь снова очистится уже сам, однако добавленный предмет на атаку будет иметь эффект. После чего можно подобрать с пола предметы героя и отдать ему триггерно.
Почему не стоит добавлять способность когтей триггерно? - потому что 2 добавленные одинаковые способности не суммируются. Два одинаковых предмета же суммируются.
Есть ли минусы у вышеописанного способа? - скорее всего удалить добавленный бонус нормально не выйдет. Придётся вытряхать инвентарь удалением способности "предметы герой" у самого героя, а это тот ещё геморрой -восстановить потом всё, что должно было остаться неудалённым.
Если я не ошибаюсь, это происходит из-за подгрузки способностей в той самой книге. Можно дать эту способность какому-нибудь юниту и поместить его на игровом поле, что подгрузка этих способностей происходила во время инициализации карты.
предмет это просто иконка которая содержит способности
книга заклинания это способность
и редактировать нужно способность "книга заклинаний"
или создать на её основе новую способность "моя книга заклинаний"
а потом у предмета просто указать способность "моя книга заклинаний"
если не хватает знаний то их можно пополнить в статьях
Rасательно вопроса как добавить в книгу заклинаний больше 12 скиллов - можно добавить книгу в книгу и новой книге сделать ещё несколько скиллов и ещё 1 или несколько книг. В каждую книгу можно ещё по книге и так далее.
Главное - ID приказа у всех книг должны быть разные.
Иконки способностей кольца, когтей и т.д. отображаться не будут, ты можешь отображать скиллы-пустышки, а (только это на всякий случай предложенный вариант!) герою выдавать сам предмет, предварительно вытряхнув из его инвентаря все предметы на пол. После добавления в пустой инвентарь нужного предмета, например когтей - заполняем ещё 4 слота предметами-пустышками, затем даём предмет со способностью "предметы герой", у этой способности для предмета должна стоять галочка "относится к предмету", обязательно. После этого инвентарь снова очистится уже сам, однако добавленный предмет на атаку будет иметь эффект. После чего можно подобрать с пола предметы героя и отдать ему триггерно.
Почему не стоит добавлять способность когтей триггерно? - потому что 2 добавленные одинаковые способности не суммируются. Два одинаковых предмета же суммируются.
Есть ли минусы у вышеописанного способа? - скорее всего удалить добавленный бонус нормально не выйдет. Придётся вытряхать инвентарь удалением способности "предметы герой" у самого героя, а это тот ещё геморрой -восстановить потом всё, что должно было остаться неудалённым.
Потому что вы блокируете мультишот. Запрет спеллбука не запрещает способности, находящиеся в нем. Но запрет самих способностей, внезапно, запрещает их.
Если нестандартная способность используется юнитом (героем), то можно убрать галочку с "Характеристики - Относится к предмету", и появятся нужные поля.
циклы+массивы
читай статьи
и все более менее нормальные карты сделаны людьми которые прочли все статьи
та же дота например(хотя она не особо нормальная)
Бтв, про сбор команды - для продвинутых сущностей нередко исправлять за другими оказывается тяжелее, чем делать самому, важно создать максимально комфортные условия для созидания, вот для чего деньги не лишние, а уж дело и самому можно делать.
И, да, тема-то не про то, надо это или не надо, а про то, как лучше это сделать, я про это и в стартовом сообщении написал.
Я на крайний сам вопрос по варианту 3 проверю и/или будет сделан выбор между третьим вариантом, вторым, каким-то ещё и отказом от Cooldown Reduction, но если кто поможет - спасибо.
Ну качаешь остюда JNGP, тут поправлено туча багов, спс Ханашиби.
Ставим по инструкции, запускаем ро, потом отрубаем USWE опции вроде там кастом тайслетов да кастом гуи триггеров, оно нафиг ненадо и нередко ломает совместимость с другими редакторами карт wc3.
Сжасс там есть, все должно изи работать.
Если нужен мемхак, скину код из своей карты с инструкциями что к чему.
Еще вопросы?
самая лучшая, на мой взгляд, связка - это отлов урона + список событий, привязанный к каждому юниту. Так сделано в YouTD, к примеру. Там даже карта есть DevKit (для создания своих башен) с открытым кодом всех систем. Там можно посмотреть, как это сделано. А так - лучше не бежать от jass, как чёрт от ладана, а сразу разобраться в нём. я в своё время разобрался в нём за пару дней, хотя к программированию вообще не имею никакого отношения. А можно делать всё в wurst сразу, а не в vjass. Короче - привычка делать всё на гуи принесёт потом проблемы, если из карты что-то приличное сделать хочется, потому что всё равно придётся всё переделывать. Да и чё такого страшного в джассе? Душу вроде никому продавать не надо за его изучение.
Вам наверное будет проще взять доспехи горного великана, а защиту не трогать.
Помнится где то была похожая тема, там формула в константах, т.е в таблице, основной дополнительный и рассчет защиты. Но как помне проще 0 защиты, тип без защиты, а доспехами великана регулируйте как душе угодно.
Т.е. ты сначала отдаешь от героя в рюкзак, а потом сразу же забираешь из рюкзака герою? И нафига? Нет, я понял, что у тебя с логикой туго, но все равно должен спросить.
Для простоты и аналогичности: создаёшь третьего юнита, кидаешь ему шмот из рюкзака, кидаешь шмот героя в рюкзак, кидаешь из третьего юнита в героя.
Новые функции в ГУИ, к примеру перемещение точек и их удаление, так же проверка скриптов, если будет ошибка в скрипте, он выдаст ошибку. Можно изменить ID объекта, удобная вещь, не запутаешься, когда переносишь скрипты со строками фиксации (к примеру точка (массив)), если нет её в проекте, она появится автоматически (удобно для переноса скрипта с болванки на проект). Оптимизация. И это ещё не все функции.
На мой взгляд удобно, но есть один минус, когда копируешь текст, он выдаёт не понятные иероглифы, приходится пару раз изменить текст, потом брать его в буфер обмена.
Сильный ии при отсутствии расходов получает по 20 единиц золота за раз. Это можно увидеть просматривая реплеи сражений, проведенных против сильного компьютера. К тому же, если посмотреть код ии, да и просто понаблюдать за поведением слабого компьютера и сильного/среднего, то можно заметить, что слабый бот начинает крипиться с задержкой, по сравнению со своими средней и сильной версиями. Сильный бот начинает апргейдить главное здание раньше, чем средний и слабый, следовательно, и исследования некоторые у него проходят раньше, второй/третий герой появляются раньше и здания соответствующие. Так же слабый не строит оборонительные сооружения на дополнительных рудниках. Как то так. К тому же, насколько я помню, слабый вроде бы вообще исследований не проводит. Ну и естественно, не всегда все работает в строгости с тем, как я описал и это верно не для всех ии, мое описание больше по ии Орды. Остальных помню плохо. Поведение ии зависит и от карты и от типов точек на ней и от того, как складывается сражение. Слабый ии вполне может обогнать по развитию среднего в некоторых случаях и так далее.
Сначала, Хоффман, думал обозвать тебя лентяем, но потом не удивился, почему ты ничего не нашел !!!
Близзарди засунули ети текстуры очень глубоко:
в архиве War3x.mpq есть архивы с названиями в виде букв английского алфавита, так вот твои заветние текстуры ето Cliff0.blp и Cliff1.blp в архиве Z.mpq.
quq_CCCP, пробовал, но что-то не получилось. вставил войска вокруг рудника, и рабы не могли войти в внутрь. Но это не из-за этого.
Все выяснил в чем дело.
нашел ответ
Сначала не понимал, почему вообще не хотело работать это. Везде тыкал, и проверял функцией, и дебагом выводил на экран. Абсолютно везде говорило, что можно передвигаться работникам (даже в воде).
Теперь врубился, почему так было. Нужно было создать блокиратор пути с PATHING_TYPE_PEONHARVESTPATHING. Было два варианта. Либо нарисовать "текстурку + декор" или через "триггеры". Хотя нарисовать текстуру в фотошопе как в статье xgm.guru/p/wc3/pathing-alternate мог, но не знал какого цвета, в статье не показано какого цвета тип PATHING_TYPE_PEONHARVESTPATHING. Или через триггеры см. карту xgm.guru/p/wc3/181384
Хотя создать блокиратор это было полбеды, нужно было понять почему не работает. Работники бегают по участку, то не бегают. Фиг поймешь. Этого можно было бы не заметить (в своей карте пришлось участок визуально рельефом приукрасить, чтобы мог отличать), чтобы понаблюдать. Потом заметил, что вурдалак неся срубленные деревья домой, начал обходить.
Работники когда идут добывать ресурсы, блокиратор их впускает (бывает и не хочет впускать). Но как только они добудут ресурсы, то получат приказ "resumeharvesting" и побегут домой. Тогда встречают в блок. И придется обходить участок. Правильно делают вурдалаки, хотя не всегда. А вот рабы орков и Альянса не правильные какие-то. Они встанут у границы, постоят 2-5 секунд. И походят у границы (туда-сюда), и находят как-будто бы "невидимую" щель, и все по одному входят.
Хотя это работает немного криво (у меня). Работники не хотят обходить участок, это раз. Во-вторых, работников могут впустить. то могут выпустить. Не понятно, что такое.
Насчет светлячков, их даже рассматривать не стал, так как добывают на одном месте.
Всем спасибо, проблему решил за счет проверки на цвет/номер игрока как индекс в массиве переменных. Все работает как запланировано.
Вопрос вдогонку: как можно задавать сам индекс переменной-массива?)
З.Ы. Массивы конечно зло, но другого способа хранить инфо по одному спеллу, не используя множество переменных - пока не умею.
Создаёт стену из магического льда, которая отталкивает противников от себя.
function IsUnitDeadBX takes unit u returns boolean
return GetUnitTypeId(u) == 0 or IsUnitType(u, UNIT_TYPE_DEAD)
endfunction
function IsTarget takes unit u,unit d returns boolean
return not IsUnitType(u,UNIT_TYPE_ANCIENT) and not IsUnitDeadBX(u) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and (IsUnitEnemy(u, GetOwningPlayer(d)) or GetOwningPlayer(u) == Player(15))
endfunction
function SQ takes real xa, real ya, real xb, real yb returns real
return SquareRoot((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb))
endfunction
function SafeX takes real pxx returns real
local real lfr=GetRectMinX(bj_mapInitialPlayableArea)+50
if(pxx<lfr)then
return lfr
endif
set lfr=GetRectMaxX(bj_mapInitialPlayableArea)-50
if(pxx>lfr)then
return lfr
endif
return pxx
endfunction
function SafeY takes real pyy returns real
local real lfr=GetRectMinY(bj_mapInitialPlayableArea)+50
if(pyy<lfr)then
return lfr
endif
set lfr=GetRectMaxY(bj_mapInitialPlayableArea)-50
if(pyy>lfr)then
return lfr
endif
return pyy
endfunction
function UBU takes unit u, unit d, unit c , real w returns boolean
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real r1 = 57.295827*Atan2(y-GetUnitY(d),x-GetUnitX(d))
local real r2 = 57.295827*Atan2(y-GetUnitY(c),x-GetUnitX(c))
set r2 = r2 -180
if r1 < 0.00 then
set r1 = r1 + 360
endif
if r2 < 0.00 then
set r2 = r2 + 360
endif
if r1 - r2 <= w and r1 - r2 >= -(w) then
return true
else
return false
endif
endfunction
function IceWallCon takes nothing returns boolean
return GetSpellAbilityId() == 'A0KP'
endfunction
function IceWallCreate takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit c = LoadUnitHandle(udg_AssassinHash,id,0)
local real r = LoadReal(udg_AssassinHash,id,3)
local integer i = LoadInteger(udg_AssassinHash,id,4)
local integer j = LoadInteger(udg_AssassinHash,id,5)
local real x = LoadReal(udg_AssassinHash,id,StringHash("X"))
local real y = LoadReal(udg_AssassinHash,id,StringHash("Y"))
local real a = 0.
local real b = 0.
local boolean e = LoadBoolean(udg_AssassinHash,id,6)
local boolean f = LoadBoolean(udg_AssassinHash,id,7)
local boolean k = LoadBoolean(udg_AssassinHash,id,8)
local integer n = LoadInteger(udg_AssassinHash,id,25)
local real X2 = LoadReal(udg_AssassinHash,id,StringHash("X2"))
local real Y2 = LoadReal(udg_AssassinHash,id,StringHash("Y2"))
local real X3 = LoadReal(udg_AssassinHash,id,StringHash("X3"))
local real Y3 = LoadReal(udg_AssassinHash,id,StringHash("Y3"))
local integer h = 0
local group g = LoadGroupHandle(udg_AssassinHash,id,2)
local unit u
local unit d
local unit d1
if e == false then
set i = i+1
set j = j+1
if i < 7 then
set a = SafeX(x+(80.*i)*Cos(r))
set b = SafeY(y+(80.*i)*Sin(r))
set d = CreateUnit(GetOwningPlayer(c),'e00V',a,b,0)
call UnitAddAbility(d,'Arav')
call UnitRemoveAbility(d,'Arav')
call SetUnitFlyHeight(d,150,0)
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",a,b))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",a,b))
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU1"+I2S(i)),d)
set a = SafeX(x-(80.*j)*Cos(r))
set b = SafeY(y-(80.*j)*Sin(r))
set d = CreateUnit(GetOwningPlayer(c),'e00V',a,b,0)
call UnitAddAbility(d,'Arav')
call UnitRemoveAbility(d,'Arav')
call SetUnitFlyHeight(d,150,0)
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",a,b))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",a,b))
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU2"+I2S(j)),d)
call SaveInteger(udg_AssassinHash,id,4,i)
call SaveInteger(udg_AssassinHash,id,5,j)
else
call SaveBoolean(udg_AssassinHash,id,6,true)
endif
else
if f == false then
call SaveInteger(udg_AssassinHash,id,4,0)
call SaveReal(udg_AssassinHash,id,3,r-1.566)
call TimerStart(t,.025,true,function IceWallCreate)
call SaveBoolean(udg_AssassinHash,id,7,true)
else
set i = i+1
if i < 201 then
call SaveInteger(udg_AssassinHash,id,4,i)
set d = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU16"))
set d1 = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU26"))
call GroupClear(udg_G)
call GroupEnumUnitsInRange(udg_G,x,y,1040,null)
loop
set u = FirstOfGroup(udg_G)
if IsTarget(u,c) and UBU(u,d,d1,20.) and IsUnitInGroup(u,g) == false then
call GroupAddUnit(g,u)
if GetUnitAbilityLevel(c,'B009') > 0 then
call UnitDamageTarget(c,u,150.+80.*GetUnitAbilityLevel(c,'A0KP'),true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null)
else
call UnitDamageTarget(c,u,75.+40.*GetUnitAbilityLevel(c,'A0KP'),true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null)
endif
set n = n+1
call SaveInteger(udg_AssassinHash,id,25,n)
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(n)),15)
if SQ(X3,Y3,GetUnitX(u),GetUnitY(u)) > SQ(X2,Y2,GetUnitX(u),GetUnitY(u)) then
call SaveReal(udg_AssassinHash,id,StringHash("IWR"+I2S(n)),LoadReal(udg_AssassinHash,id,20))
else
call SaveReal(udg_AssassinHash,id,StringHash("IWR"+I2S(n)),LoadReal(udg_AssassinHash,id,21))
endif
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(n)),u)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\FrostArrows\\NagaColdArrowMissile.mdl",u,"chest"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",u,"chest"))
endif
call GroupRemoveUnit(udg_G,u)
exitwhen u == null
endloop
set i = 1
if n > 0 then
loop
exitwhen i > n
set h = LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)))-1
set r = LoadReal(udg_AssassinHash,id,StringHash("IWR"+I2S(i)))
set u = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(i)))
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)),h)
call SetUnitPathing(u,false)
call SetUnitX(u,SafeX(GetUnitX(u)+15.*Cos(r)))
call SetUnitY(u,SafeY(GetUnitY(u)+15.*Sin(r)))
call IssueImmediateOrder(u,"stop")
if ModuloInteger(h,3) == 0 then
call DestroyEffect(AddSpecialEffectTarget("FrozenOrbBall.mdx",u,"chest"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",u,"chest"))
endif
set i = i + 1
endloop
set i = 1
loop
exitwhen i > n
set h = LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)))
set u = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(i)))
if h <= 0 or IsUnitDeadBX(u) or not IsTarget(u,c) then
set j = i
call GroupRemoveUnit(g,u)
call SetUnitPathing(u,true)
loop
exitwhen j > n
call SaveReal(udg_AssassinHash,id,StringHash("IWR"+I2S(j)),LoadReal(udg_AssassinHash,id,StringHash("IWR"+I2S(j+1))))
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(j)),LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(j+1))))
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(j)),LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(j+1))))
set j = j + 1
endloop
set n = n-1
call SaveInteger(udg_AssassinHash,id,25,n)
endif
set i = i + 1
endloop
endif
else
set i = 1
if n > 0 then
loop
exitwhen i > n
set h = LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)))-1
set r = LoadReal(udg_AssassinHash,id,StringHash("IWR"+I2S(i)))
set u = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(i)))
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)),h)
call SetUnitPathing(u,false)
call SetUnitX(u,SafeX(GetUnitX(u)+15.*Cos(r)))
call SetUnitY(u,SafeY(GetUnitY(u)+15.*Sin(r)))
call IssueImmediateOrder(u,"stop")
if ModuloInteger(h,3) == 0 then
call DestroyEffect(AddSpecialEffectTarget("FrozenOrbBall.mdx",u,"chest"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",u,"chest"))
endif
set i = i + 1
endloop
set i = 1
loop
exitwhen i > n
set h = LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)))
set u = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(i)))
if h <= 0 or IsUnitDeadBX(u) then
set j = i
call GroupRemoveUnit(g,u)
call SetUnitPathing(u,true)
loop
exitwhen j > n
call SaveReal(udg_AssassinHash,id,StringHash("IWR"+I2S(j)),LoadReal(udg_AssassinHash,id,StringHash("IWR"+I2S(j+1))))
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(j)),LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(j+1))))
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(j)),LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(j+1))))
set j = j + 1
endloop
set n = n-1
call SaveInteger(udg_AssassinHash,id,25,n)
endif
set i = i + 1
endloop
endif
if k == false then
set j = 1
loop
exitwhen j > 6
set d = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU1"+I2S(j)))
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",GetUnitX(d),GetUnitY(d)))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",GetUnitX(d),GetUnitY(d)))
call KillUnit(d)
set j = j + 1
endloop
set j = 1
loop
exitwhen j > 6
set d = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU2"+I2S(j)))
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",GetUnitX(d),GetUnitY(d)))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",GetUnitX(d),GetUnitY(d)))
call KillUnit(d)
set j = j + 1
endloop
set d = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"))
call KillUnit(d)
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",GetUnitX(d),GetUnitY(d)))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",GetUnitX(d),GetUnitY(d)))
call SaveBoolean(udg_AssassinHash,id,8,true)
endif
if k and n <= 0 then
call DestroyGroup(g)
call DestroyTimer(t)
call FlushChildHashtable(udg_AssassinHash,id)
endif
endif
endif
endif
set t = null
set c = null
set d = null
set d1 = null
set g = null
set u = null
endfunction
function IceWall takes nothing returns nothing
local unit c = GetSpellAbilityUnit()
local real a = GetUnitX(c)
local real b = GetUnitY(c)
local real x = SafeX(GetSpellTargetX())
local real y = SafeY(GetSpellTargetY())
local real r = Atan2(y-b,x-a)+1.566
local timer t = CreateTimer()
local real dist = SQ(a,b,x,y)*2.
local integer id = GetHandleId(t)
local unit d
set d = CreateUnit(GetOwningPlayer(c),'e00V',x,y,0)
call UnitAddAbility(d,'Arav')
call UnitRemoveAbility(d,'Arav')
call SetUnitFlyHeight(d,150,0)
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU"),d)
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",x,y))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",x,y))
call SaveUnitHandle(udg_AssassinHash,id,0,c)
call SaveReal(udg_AssassinHash,id,3,r)
set r = Atan2(y-b,x-a)
call SaveReal(udg_AssassinHash,id,20,r)
call SaveReal(udg_AssassinHash,id,21,Atan2(b-y,a-x))
call SaveReal(udg_AssassinHash,id,StringHash("X2"),a+dist*Cos(r))
call SaveReal(udg_AssassinHash,id,StringHash("Y2"),b+dist*Sin(r))
call SaveReal(udg_AssassinHash,id,StringHash("X3"),a)
call SaveReal(udg_AssassinHash,id,StringHash("Y3"),b)
call SaveGroupHandle(udg_AssassinHash,id,2,CreateGroup())
call SaveReal(udg_AssassinHash,id,StringHash("X"),x)
call SaveReal(udg_AssassinHash,id,StringHash("Y"),y)
call TimerStart(t,.025,true,function IceWallCreate)
set t = null
set c = null
set d = null
endfunction
JackFastGame, старый знакомый баг с каналом из доты, лекарство только одно применять для канала ID приказа которых больше не будет ни у 1 юнита, или все способности ID приказа которых ты копируешь для канала, должны появится у юнитов и быть применены до того как твои герои выучат способность на основе канала.
Движок вара кеширует приказ и тип цели для этого приказа, поэтому триггерно невозможно отдать приказ, у него по мнению движка другой тип цели.
Нельзя применить высасывание жизни на юнита, потому что записано что для этого приказа не требуется цель...
Подробности можно спросить у DracoL1ch.
Самый простой алгоритм - для каждого юнита-цели создаешь даммик (Юнит со способностью москиты 'Aloc', без модели, тени и с отключенной атакой), который, получив нужный приказ, радостно кидает корни с нужными параметрами в оную цель. Не забудь применить к даммику ограничение времени жизни, чтобы он скастовал и благополучно сдох.
Герою же просто выдаешь пустышку на основе нейтрально-враждебной геройской способности Канал, срабатывание которой и отлавливаешь триггером, делающим вышеуказанные действия.
» WarCraft 3 / Сломалась карта
» WarCraft 3 / TimerGetRemaining
» WarCraft 3 / Установка
» WarCraft 3 / Герои войска из кампании.
» WarCraft 3 / Таймеры
» WarCraft 3 / Не получается изменить цвет игрока.
» WarCraft 3 / Как сделать поворот камеры
» WarCraft 3 / Триггеры не работают
» WarCraft 3 / Радиус обзора юнита
» WarCraft 3 / Редактор моделей
» StarCraft 2 / Юниты и модели
» WarCraft 3 / Вопрос по Jass
» WarCraft 3 / Вопрос по Jass
» WarCraft 3 / Новый редактор
» WarCraft 3 / Вопрос по Jass
» WarCraft 3 / Книга Заклинаний
» WarCraft 3 / Вопрос по JNGP
» WarCraft 3 / Мемхак, запуск кд
» WarCraft 3 / Как убрать звук у модели?
» WarCraft 3 / Про JNGP
» WarCraft 3 / Поглощение урона
» WarCraft 3 / Способность передачи юнита игроку
» WarCraft 3 / Отличия
» WarCraft 3 / Ландшафт и склон
» WarCraft 3 / Проблемы с триггерными способностями